1 //------------------------------------------------------------------------------
2 // <copyright file="io.cs" company="Microsoft">
4 // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
6 // The use and distribution terms for this software are contained in the file
7 // named license.txt, which can be found in the root of this distribution.
8 // By using this software in any fashion, you are agreeing to be bound by the
9 // terms of this license.
11 // You must not remove this notice, or any other, from this software.
14 //------------------------------------------------------------------------------
22 using System
.Reflection
;
27 private FileStream ifile
;
28 private StreamReader rfile
;
30 private FileStream lst_ofile
;
31 private StreamWriter lst_wfile
;
33 private static String ifilename
;
34 private static String ofilename
;
35 private static String lst_ofilename
;
36 private static String classname
;
38 public static bool gendebug
= false;
39 public static bool genexe
= true; // default to generating exe's
40 public static bool gendll
= false;
41 public static bool genlist
= false;
42 public static string genpath
= "."; // default output directory to current dir
44 private String
[] args
;
51 /* variable declarations */
52 private char look
; /* lookahead character */
53 private StringBuilder buf
; /* buffer for comment tracking */
54 int bufline
= 0; // current line matching buffer
55 int curline
= 0; // current comment line number
57 public static string GetClassname()
62 public String
GetInputFilename()
66 /* read new character from input stream */
67 public void ReadChar()
69 if (_eof
) // if already eof, nothing to do here
71 if (ibuf
== null || ibufidx
>= MyC
.MAXBUF
)
73 ibuf
= new char[MyC
.MAXBUF
];
75 ibufread
= rfile
.Read(ibuf
, 0, MyC
.MAXBUF
);
78 buf
= new StringBuilder(MyC
.MAXSTR
);
80 look
= ibuf
[ibufidx
++];
81 if (ibufread
< MyC
.MAXBUF
&& ibufidx
> ibufread
)
85 * track the read characters
92 public char getNextChar()
97 public void Abort(string s
)
99 StringBuilder sb
= new StringBuilder();
100 sb
.Append(ifilename
);
102 sb
.Append(curline
+1);
103 sb
.Append(") : error M0000: ");
105 Console
.WriteLine(sb
.ToString());
106 throw new ApplicationException("Aborting compilation");
109 public static void ICE(string s
) // internal compiler error
111 StringBuilder sb
= new StringBuilder();
112 sb
.Append(ifilename
);
113 sb
.Append("(0) : error M9999: Internal Compiler Error: ");
115 Console
.WriteLine(sb
.ToString());
116 throw new ApplicationException("Aborting compilation");
125 Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
130 if (args
[i
][0] != '/')
132 if (args
[i
].Equals("/?"))
134 Console
.WriteLine("Compiler options:\n myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
137 if (args
[i
].Equals("/debug"))
143 if (args
[i
].Equals("/nodebug"))
149 if (args
[i
].Equals("/exe"))
156 if (args
[i
].Equals("/dll"))
163 if (args
[i
].Equals("/list"))
169 if (args
[i
].Length
> 8 && args
[i
].Substring(0,8).Equals("/outdir:"))
171 genpath
= args
[i
].Substring(8);
176 * exit if no switch matched
178 Abort("Unmatched switch = '"+args
[i
]+"'\nArguments are:\nmyc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
181 if (args
.Length
-i
!= 1)
183 Abort("myc [/debug] [/nodebug] [/list] [/dll] [/exe] [/outdir:path] filename.myc\n");
185 ifilename
= args
[args
.Length
-1]; // filename is last
188 public Io(String
[] a
)
195 ifile
= new FileStream(ifilename
, FileMode
.Open
,
196 FileAccess
.Read
, FileShare
.Read
, 8192);
199 Abort("Could not open file '"+ifilename
+"'\n");
201 rfile
= new StreamReader(ifile
); // open up a stream for reading
204 * for now we are going to create a default class using the filename
206 i
= ifilename
.LastIndexOf('.');
208 Abort("Bad filename '"+ifilename
+"'");
209 int j
= ifilename
.LastIndexOf('\\');
215 classname
= ifilename
.Substring(j
,i
-j
);
217 ofilename
= classname
+".exe";
219 ofilename
= classname
+".dll";
222 lst_ofilename
= classname
+".lst";
223 lst_ofile
= new FileStream(lst_ofilename
, FileMode
.Create
,
224 FileAccess
.Write
, FileShare
.Write
, 8192);
225 if (lst_ofile
== null)
226 Abort("Could not open file '"+ofilename
+"'\n");
227 lst_wfile
= new StreamWriter(lst_ofile
);
231 public void Out(String s
)
233 lst_wfile
.Write(s
); // write the buffer
234 lst_wfile
.Flush(); // slow, but useful
254 public String
commentEndPreTok(String s
)
257 Console
.Write("commentEndPreTok1 S=["+s
+"], buf=");
258 for (int _debug_i
=0; _debug_i
<buf
.Length
;_debug_i
++)
260 int _debug_d
= buf
[_debug_i
];
261 char _debug_c
= (char) (_debug_d
+ 96);
263 Console
.Write("^"+Char
.ToString(_debug_c
));
265 Console
.Write(buf
[_debug_i
]);
267 Console
.Write(_debug_d
);
270 Console
.WriteLine(";");
273 * many times we will already have parsed source code past the point
274 * that we want to emit. We will use the token given to backup.
277 if (s
== null) // make sure we have something
279 b
= buf
.ToString(); // have to convert first
280 int i
= b
.LastIndexOf(s
); // find this token in buffer
281 String c
= b
.Substring(0,i
).Trim(); // copy as comment
282 buf
= new StringBuilder(b
.Substring(i
), MyC
.MAXSTR
); // remake buffer
284 * need to update curline to be in synch with last emitted comment
287 for (int ci
= 0; ci
< buf
.Length
; ci
++)
291 Console
.Write("commentEndPreTok2 buf=");
292 for (int _debug_i
=0; _debug_i
<buf
.Length
;_debug_i
++)
294 int _debug_d
= buf
[_debug_i
];
295 char _debug_c
= (char) (_debug_d
+ 96);
297 Console
.Write("^"+_debug_c
);
299 Console
.Write(buf
[_debug_i
]);
301 Console
.Write(_debug_d
);
304 Console
.WriteLine(";");
309 public String
commentEndTok(String s
)
312 Console
.Write("commentEndTok1 S=["+s
+"], buf=");
313 for (int _debug_i
=0; _debug_i
<buf
.Length
;_debug_i
++)
315 int _debug_d
= buf
[_debug_i
];
316 char _debug_c
= (char) (_debug_d
+ 96);
318 Console
.Write("^"+_debug_c
);
320 Console
.Write(buf
[_debug_i
]);
322 Console
.Write(_debug_d
);
325 Console
.WriteLine(";");
329 * variant to include this token at end of comment
332 if (s
== null) // make sure we have something
334 b
= buf
.ToString(); // have to convert first
335 int i
= b
.LastIndexOf(s
); // find this token in buffer
336 String c
= b
.Substring(0,i
+s
.Length
).Trim(); // copy as comment
337 buf
= new StringBuilder(b
.Substring(i
+s
.Length
), MyC
.MAXSTR
); // remake buffer
339 * need to update curline to be in synch with last emitted comment
342 for (int ci
= 0; ci
< buf
.Length
; ci
++)
346 Console
.Write("commentEndTok2 buf=");
347 for (int _debug_i
=0; _debug_i
<buf
.Length
;_debug_i
++)
349 int _debug_d
= buf
[_debug_i
];
350 char _debug_c
= (char) (_debug_d
+ 96);
352 Console
.Write("^"+_debug_c
);
354 Console
.Write(buf
[_debug_i
]);
356 Console
.Write(_debug_d
);
359 Console
.WriteLine(";");
364 public void commentBegin(String s
)
367 if (s
== null) // make sure we have something
369 b
= buf
.ToString(); // have to convert first
370 int i
= b
.IndexOf(s
); // find this token in buffer
372 i
= b
.Length
; // if not found, use whole string
373 buf
= new StringBuilder(b
.Substring(i
), MyC
.MAXSTR
); // remake buffer from substr
375 * need to update curline to be in synch with last emitted comment
378 for (int ci
= 0; ci
< buf
.Length
; ci
++)
382 Console
.Write("commentBegin S=["+s
+"], buf=");
383 for (int _debug_i
=0; _debug_i
<buf
.Length
;_debug_i
++)
385 int _debug_d
= buf
[_debug_i
];
386 char _debug_c
= (char) (_debug_d
+ 96);
388 Console
.Write("^"+_debug_c
);
390 Console
.Write(buf
[_debug_i
]);
392 Console
.Write(_debug_d
);
395 Console
.WriteLine(";");
399 public int commentGetCurrentLine()
404 public static string GetOutputFilename()